#include <iostream>
#include <map>
#include <sys/epoll.h>
#include <unistd.h>
#include <cstring>
#include "Sock.hpp"

using namespace std;

const int MAX_EVENTS = 10;
const int BUF_SIZE = 1024;

map<string, string> translation_map = {
    {"Hello", "你好"}
};

void HandleClient(int clientfd)
{
    char buf[BUF_SIZE];
    ssize_t n;
    
    while ((n = read(clientfd, buf, sizeof(buf))) > 0) {
        buf[n] = 0;
        std::string msg(buf);
        std::cout << "Received: " << msg << std::endl;

        std::string resp = translation_map[msg];
        if(resp.empty()) {
            resp = "Sorry, I don't understand.";
        }

        send(clientfd, resp.c_str(), resp.size(), 0);
    }

    if (n == 0) {
        std::cout << "Client disconnected." << std::endl;
        close(clientfd);
    } else if (n < 0 && (errno != EAGAIN && errno != EWOULDBLOCK)) {
        perror("read");
        close(clientfd);
    }
}

int main()
{
    int serverSock = Sock::Socket();
    Sock::Bind(serverSock, 8080);
    Sock::Listen(serverSock);

    int epollfd = epoll_create1(0); // 创建epoll实例
    if (epollfd < 0) {
        perror("epoll_create1 error");
        return 1;
    }

    epoll_event ev{}, events[MAX_EVENTS]; // ev用于注册事件，events用于接收事件
    ev.events = EPOLLIN; // 监听读事件
    ev.data.fd = serverSock;
    if(epoll_ctl(epollfd, EPOLL_CTL_ADD, serverSock, &ev) < 0) { // 将serverSock加入epoll实例
        perror("epoll_ctl error");
        return 1;
    }

    while(true) // 等待事件发生
    {
        int nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
        if (nfds < 0) {
            perror("epoll_wait error");
            return 1;
        }

        for (int i = 0; i < nfds; ++i) {
            if(events[i].data.fd == serverSock) { // 有新的连接
                std::string clientIP;
                uint16_t clientPort;
                int clientfd = Sock::Accept(serverSock, &clientIP, &clientPort);
                ev.events = EPOLLIN | EPOLLET; // 设置为边缘触发
                ev.data.fd = clientfd; 
                if(epoll_ctl(epollfd, EPOLL_CTL_ADD, clientfd, &ev) < 0) { // 将clientSock加入epoll实例
                    perror("epoll_ctl error");
                    close(clientfd);
                }
            } else {
                HandleClient(events[i].data.fd);
            }
        }
    }

    close(serverSock);
    close(epollfd);
    return 0;
}